package com.CST.service.impl.cb;

import com.CST.common.api.ResultObject;
import com.CST.entity.cb.BdOrganization;
import com.CST.entity.cb.EtlAccount;
import com.CST.mapper.cst.cb.EtlAccountMapper;
import com.CST.service.cb.IEtlAccountService;
import com.CST.util.ExcelTransfer;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class EtlAccountServiceImpl extends ServiceImpl<EtlAccountMapper, EtlAccount> implements IEtlAccountService {

    @Autowired
    private EtlAccountMapper etlAccountMapper;

    @Autowired
    private ExcelTransfer<BdOrganization> excelTransfer;

    @Autowired
    private ExcelTransfer<EtlAccount> excelTransferT;

    @Override
    public ResultObject getEtlAccountSource(EtlAccount etlAccount) {
        List<EtlAccount> etlAccountList = etlAccountMapper.getEtlAccountSource(etlAccount);
        return ResultObject.successReturn(etlAccountList);
    }

    @Override
    public ResultObject getEtlAccountOrgationSource(EtlAccount etlAccount) {
        if ("Income".equals(etlAccount.getSysid())) {
            etlAccount.setEdParentCode("RD_IncomeUFIDARelation");
        } else if ("Cost".equals(etlAccount.getSysid())) {
            etlAccount.setEdParentCode("RD_CostUFIDARelation");
        } else {

        }
        List<EtlAccount> etlAccountList = etlAccountMapper.getEtlAccountOrgationSource(etlAccount);
        return ResultObject.successReturn(etlAccountList);
    }


    private List<EtlAccount> tree(List<EtlAccount> etlAccountList) {
        String i = "1";
        List<EtlAccount> collect = etlAccountList.parallelStream().filter(f -> f.getParentcode().equals(i))
                .peek(e -> e.setChild(child(etlAccountList, e, String.valueOf(Integer.parseInt(i) + 1))))
                .collect(Collectors.toList());
        return collect;
    }

    private List<EtlAccount> child(List<EtlAccount> etlAccountList, EtlAccount e, String i) {
        return etlAccountList.parallelStream().filter(f -> f.getParentcode().equals(i))
                .filter(f -> f.getAccountcode().startsWith(e.getAccountcode()))
                .peek(p -> p.setChild(child(etlAccountList, p, String.valueOf(Integer.parseInt(i) + 1))))
                .collect(Collectors.toList());
    }


    @Override
    public void exportExcel(HttpServletResponse response, EtlAccount dto) throws ClassNotFoundException {
        if ("Income".equals(dto.getSysid())) {
            dto.setEdParentCode("RD_IncomeUFIDARelation");
            dto.setSheet("收入-用友系统");
        } else if ("Cost".equals(dto.getSysid())) {
            dto.setEdParentCode("RD_CostUFIDARelation");
            dto.setSheet("成本-用友系统");
        }
        List<EtlAccount> etlAccountList = etlAccountMapper.getEtlAccountOrgationSource(dto);
//        List<EtlAccount> tree = tree(etlAccountList);
        excelTransferT.exportExcel(response, etlAccountList,dto.getSheet(), "sheet", this);
    }

    @Override
    public void getCostOfUfDownLoadExcel(EtlAccount requestInfo) throws IOException {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert servletRequestAttributes != null;
        HttpServletResponse response = servletRequestAttributes.getResponse();
        if ("Income".equals(requestInfo.getSysid())) {
            requestInfo.setEdParentCode("RD_IncomeUFIDARelation");
            requestInfo.setSheet("收入-用友系统");
        } else if ("Cost".equals(requestInfo.getSysid())) {
            requestInfo.setEdParentCode("RD_CostUFIDARelation");
            requestInfo.setSheet("成本-用友系统");
        }
        String filename = requestInfo.getSheet();
        List<EtlAccount> list = etlAccountMapper.getEtlAccountOrgationSource(requestInfo);

        Set<String> set = list.stream().filter(t-> "1".equals(t.getParentcode())).map(t->t.getAccountcode()).collect(Collectors.toSet());
        assert response != null;
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), EtlAccount.class)
                .sheet("sheet")
                .registerWriteHandler(new CellWriteHandler() {
                    Integer i = null;
                    @Override
                    public void afterCellDispose(CellWriteHandlerContext context) {
                        //CellWriteHandler.super.afterCellDispose(context);
                        if (BooleanUtils.isNotTrue(context.getHead())) {
                            // 第一个单元格
                            // 只要不是头 一定会有数据 当然fill的情况 可能要context.getCellDataList() ,这个需要看模板，因为一个单元格会有多个 WriteCellData
                            WriteCellData<?> cellData = context.getFirstCellData();
                            WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();
                            // writeCellStyle.getWriteFont().setBold(true);
                            if (set.contains(cellData.getStringValue()) || cellData.getRowIndex().equals(i)) {
                                WriteFont font = new WriteFont();
                                font.setBold(true);
                                writeCellStyle.setWriteFont(font);
                                i = cellData.getRowIndex();
                            }
                        }
                    }
                })
                .doWrite(list);
    }
}
